package br.com.ctm.advogadope.rest.impl;

import java.util.List;

import javax.inject.Inject;
import javax.inject.Named;
import javax.persistence.PersistenceException;
import javax.ws.rs.Consumes;
import javax.ws.rs.DELETE;
import javax.ws.rs.FormParam;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.PUT;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;

import org.jboss.resteasy.annotations.providers.jaxb.Wrapped;

import br.com.ctm.advogadope.model.Advogado;
import br.com.ctm.advogadope.model.Processo;
import br.com.ctm.advogadope.model.Tribunal.TipoJuizo;
import br.com.ctm.advogadope.model.Usuario;
import br.com.ctm.advogadope.negocio.api.AdvogadoNegocio;
import br.com.ctm.advogadope.negocio.api.ProcessoNegocio;
import br.com.ctm.advogadope.negocio.api.UsuarioNegocio;
import br.com.framework.negocio.exception.NegocioException;

/**
 * @author Cleber
 *
 */
@Path("processos")
@Named
public class ProcessoResource extends EntityResourceImpl<Processo, ProcessoNegocio> {
	
	@Inject
	private UsuarioNegocio usuarioNegocio;
	
	@Inject
	private AdvogadoNegocio advogadoNegocio;
	

	/* (non-Javadoc)
	 * @see br.com.ctm.advogadope.rest.api.EntityResourceImpl#setNegocio(br.com.framework.negocio.api.BaseNegocio)
	 */
	@Override
	@Inject
	protected void setNegocio(ProcessoNegocio negocio) {
		super.setNegocio(negocio);
	}

	/* (non-Javadoc)
	 * @see br.com.ctm.advogadope.rest.api.EntityResource#findByID(java.lang.Long)
	 */
	@Override
	@GET
	@Path("{id}")
	@Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
	public Processo findByID(@PathParam("id") Long id) throws PersistenceException {
		return super.findByID(id);
	}

	/* (non-Javadoc)
	 * @see br.com.ctm.advogadope.rest.api.EntityResource#findAll()
	 */
	@Override
	@GET
	@Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
	@Wrapped(element = "processos")
	public List<Processo> findAll() throws PersistenceException {
		return super.findAll();
	}

	/* (non-Javadoc)
	 * @see br.com.ctm.advogadope.rest.api.EntityResource#findAll(int, int)
	 */
	@Override
	@GET
	@Path("paginated/{firstResult}/{maxResults}")
	@Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
	@Wrapped(element = "processos")
	public List<Processo> findAll(@PathParam("firstResult") int firstResult, @PathParam("maxResults") int maxResults)
			throws PersistenceException {
		return super.findAll(firstResult, maxResults);
	}

	/* (non-Javadoc)
	 * @see br.com.ctm.advogadope.rest.api.EntityResource#findByExample(br.com.framework.persistencia.model.BaseEntity)
	 */
	@Override
	@GET
	@Consumes({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
	@Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
	@Wrapped(element = "processos")
	public List<Processo> findByExample(Processo entidade)
			throws PersistenceException {
		return super.findByExample(entidade);
	}

	/* (non-Javadoc)
	 * @see br.com.ctm.advogadope.rest.api.EntityResource#getRecordCount()
	 */
	@Override
	@GET
	@Path("count")
	@Produces(MediaType.TEXT_PLAIN)
	public Long getRecordCount() throws PersistenceException {
		return super.getRecordCount();
	}

	/* (non-Javadoc)
	 * @see br.com.ctm.advogadope.rest.api.EntityResource#insert(br.com.framework.persistencia.model.BaseEntity)
	 */
	@Override
	@POST
	@Consumes({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
	public Response insert(Processo entidade) throws NegocioException,
			PersistenceException {
		return super.insert(entidade);
	}

	/* (non-Javadoc)
	 * @see br.com.ctm.advogadope.rest.api.EntityResource#update(java.lang.Long, br.com.framework.persistencia.model.BaseEntity)
	 */
	@Override
	@PUT
	@Path("{id}")
	@Consumes({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
	public Response update(@PathParam("id") Long id, Processo entidade) throws NegocioException,
			PersistenceException {
		return super.update(id, entidade);
	}

	/* (non-Javadoc)
	 * @see br.com.ctm.advogadope.rest.api.EntityResource#remove(java.lang.Long)
	 */
	@Override
	@DELETE
	@Path("{id}")
	public Response remove(@PathParam("id") Long id) throws NegocioException,
			PersistenceException {
		return super.remove(id);
	}

	@POST
	@Path("consultarProcesso")
	@Consumes(MediaType.APPLICATION_FORM_URLENCODED)
	@Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
	public Processo consultarProcesso(@FormParam("npu") String npu, @FormParam("idTribunal") Long idTribunal, @FormParam("tipoJuizo") String tipoJuizo) throws NegocioException, PersistenceException {
		Processo processo = getNegocio().consultarProcesso(npu, idTribunal, TipoJuizo.valueOf(tipoJuizo));
		return processo;
	}
	
	@POST
	@Path("consultarProcessosPorCliente")
	@Consumes(MediaType.APPLICATION_FORM_URLENCODED)
	@Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
	@Wrapped(element = "processos")
	public List<Processo> consultarProcessosPorCliente(@FormParam("email") String email) throws PersistenceException {
		Usuario usuario = usuarioNegocio.findByEmail(email);
		List<Processo> processos = getNegocio().findByAdvogado(usuario.getAdvogado(), -1, -1, true);
		return processos;
	}
	
	@POST
	@Path("adicionarProcessoCliente")
	@Consumes(MediaType.APPLICATION_FORM_URLENCODED)
	@Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
	public Response adicionarProcessoCliente(@FormParam("npu") String npu, @FormParam("idTribunal") Long idTribunal, 
			@FormParam("tipoJuizo") String tipoJuizo, @FormParam("email") String email) throws NegocioException, PersistenceException {
		Processo processo = consultarProcesso(npu, idTribunal, tipoJuizo);
		Usuario usuario = usuarioNegocio.findByEmail(email);
		Response response = null;
		if (usuario != null && processo != null) {
			usuario.getAdvogado().getProcessos().add(processo);
			try {
				advogadoNegocio.update((Advogado)usuario.getAdvogado());
				response = Response.created(uriInfo.getAbsolutePath()).build();
			} catch (Exception e) {
				LOGGER.error(String.format("Falha ao associar processo %s ao cliente %s", npu, email), e);
				response = Response.serverError().build();
			}
		} else {
			LOGGER.warn(String.format("Processo %s e/ou cliente %s, não encontrado(s)", npu, email));
			response = Response.serverError().build();
		}
		return response;
		
	}
	
	@POST
	@Path("removerProcessoCliente")
	@Consumes(MediaType.APPLICATION_FORM_URLENCODED)
	@Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
	public Response removerProcessoCliente(@FormParam("npu") String npu, @FormParam("idTribunal") Long idTribunal, 
			@FormParam("tipoJuizo") String tipoJuizo, @FormParam("email") String email) throws NegocioException, PersistenceException {
		Processo processo = consultarProcesso(npu, idTribunal, tipoJuizo);
		Usuario usuario = usuarioNegocio.findByEmail(email);
		Response response = null;
		if (usuario != null && processo != null) {
			usuario.getAdvogado().getProcessos().remove(processo);
			try {
				advogadoNegocio.update((Advogado)usuario.getAdvogado());
				response = Response.ok().build();
			} catch (Exception e) {
				LOGGER.error(String.format("Falha ao associar processo %s ao cliente %s", npu, email), e);
				response = Response.serverError().build();
			}
		} else {
			LOGGER.warn(String.format("Processo %s e/ou cliente %s, não encontrado(s)", npu, email));
			response = Response.serverError().build();
		}
		return response;
		
	}
	
}
